package com.dbflow5.models;

import com.dbflow5.StringUtils;
import com.dbflow5.TestDatabase;
import com.dbflow5.annotation.TypeConverter;
import com.dbflow5.converter.TypeConverters;
import com.dbflow5.annotation.Column;
import com.dbflow5.annotation.ForeignKey;
import com.dbflow5.annotation.ForeignKeyAction;
import com.dbflow5.annotation.Index;
import com.dbflow5.annotation.IndexGroup;
import com.dbflow5.annotation.NotNull;
import com.dbflow5.annotation.PrimaryKey;
import com.dbflow5.annotation.Table;
import com.dbflow5.structure.BaseModel;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ProspectQuizs {

    @TypeConverter
    public static class MutableSetTypeConverter extends TypeConverters.TypeConverter<String, Set<String>> {
        @Override
        public String getDBValue(Set<String> model) {
            if (model != null) {
                return StringUtils.joinToString(model, ", ");
            }
            return null;
        }

        @Override
        public Set<String> getModelValue(String data) {
            if (data != null) {
                List<String> list = Arrays.asList(data.split(""));
                return new HashSet<>(list);
            }
            return null;
        }
    }


    /*
     * A quiz, consisting primarily of a question from the current user, and a set of responses from
     * prospects and/or prior prospects that the user has acted upon. Though the author ID is needed on the server, the
     * client has no need of it. Instead, just the canonical quiz identifier is used.
     * It is envisioned that the resolvedResponses may be provided only when an additional parameter is
     * specified in the request.
     */
    @Table(database = TestDatabase.class, allFields = true, useBooleanGetterSetters = false, indexGroups = {@IndexGroup(number = 1, name = "modified")})
    public static class ProspectQuiz extends BaseModel {
        @NotNull
        @PrimaryKey
        public String ID;

        @NotNull
        public String question;

        @NotNull
        public int pendingResponseCount;

        @NotNull
        public int resolvedResponseCount;

        @NotNull
        public int newResponseCount;

        // We have a list of prospect IDs that have been invited but not answered. Just IDs to be used
        // with determining who can still be added.
        @NotNull
        @Column(typeConverter = MutableSetTypeConverter.class)
        public Set<String> pendingUnanswered;

        @Index(indexGroups = {1})
        @Column(defaultValue = "1L")
        public long modifiedDate;

        public String getID() {
            return ID;
        }

        public void setID(String ID) {
            this.ID = ID;
        }

        public String getQuestion() {
            return question;
        }

        public void setQuestion(String question) {
            this.question = question;
        }

        public int getPendingResponseCount() {
            return pendingResponseCount;
        }

        public void setPendingResponseCount(int pendingResponseCount) {
            this.pendingResponseCount = pendingResponseCount;
        }

        public int getResolvedResponseCount() {
            return resolvedResponseCount;
        }

        public void setResolvedResponseCount(int resolvedResponseCount) {
            this.resolvedResponseCount = resolvedResponseCount;
        }

        public int getNewResponseCount() {
            return newResponseCount;
        }

        public void setNewResponseCount(int newResponseCount) {
            this.newResponseCount = newResponseCount;
        }

        public Set<String> getPendingUnanswered() {
            return pendingUnanswered;
        }

        public void setPendingUnanswered(Set<String> pendingUnanswered) {
            this.pendingUnanswered = pendingUnanswered;
        }

        public long getModifiedDate() {
            return modifiedDate;
        }

        public void setModifiedDate(long modifiedDate) {
            this.modifiedDate = modifiedDate;
        }

        public ProspectQuiz(String quizID) {
            this();
            ID = quizID;
        }

        public ProspectQuiz() {
            question = "";
            pendingResponseCount = 0;
            resolvedResponseCount = 0;
            newResponseCount = 0;
            pendingUnanswered = new HashSet<>();
        }
    }

    /**
     * An element of a quiz, consisting of a user the quiz targeted and his/her response
     * Status is only used on the quiz full view, in which profiles that have been rejected or matched
     * will be included in the quiz, but shown separately. In the quiz full view, a participant whose
     * account is deactivated or deleted should never be visible. When a quiz is refreshed and a participant
     * deleted or deactivated the account, the entry for the deleted user will disappear from the response.
     */
    @Table(database = TestDatabase.class, allFields = true, useBooleanGetterSetters = false, indexGroups = {@IndexGroup(number = 1, name = "quizid_answerts")})
    public static class ProspectQuizEntry extends BaseModel {
        @PrimaryKey
        @NotNull
        public String profileID;

        @PrimaryKey
        @NotNull
        @Index(indexGroups = {1})
        @ForeignKey(stubbedRelationship = true,
                tableClass = ProspectQuiz.class,
                onDelete = ForeignKeyAction.CASCADE)
        public String quizID;

        //@ForeignKey(saveForeignKeyModel = true) var photo: PhotoMedia?
        public String text;
        public QuizParticipantStatus participantStatus;

        @NotNull
        public String name;

        @NotNull
        @Index(indexGroups = {1})
        public long answerEpoch;

        public String getProfileID() {
            return profileID;
        }

        public void setProfileID(String profileID) {
            this.profileID = profileID;
        }

        public String getQuizID() {
            return quizID;
        }

        public void setQuizID(String quizID) {
            this.quizID = quizID;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

        public QuizParticipantStatus getParticipantStatus() {
            return participantStatus;
        }

        public void setParticipantStatus(QuizParticipantStatus participantStatus) {
            this.participantStatus = participantStatus;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public long getAnswerEpoch() {
            return answerEpoch;
        }

        public void setAnswerEpoch(long answerEpoch) {
            this.answerEpoch = answerEpoch;
        }

        public ProspectQuizEntry() {
            //photo = null
            text = null;
            participantStatus = null;
            name = "";
            //new = false
            answerEpoch = 0;
        }
    }

    enum QuizParticipantStatus {
        Pending,
        Rejected,
        Connected,
        ;

        public static QuizParticipantStatus fromCode(int code) {
            switch (code) {
                case 0:
                    return Pending;
                case 1:
                    return Rejected;
                case 2:
                    return Connected;
                default:
                    throw new IllegalArgumentException("Invalid raw int for QuizParticipantStatus");
            }
        }
    }
}
